/*基础数据类型转二进制数组的helper方法
 * 大部分代码来自GPT，功能ok. todo:未推敲最合理和最高效的方法
 * */

const HexCharacters = '0123456789abcdef';

class DataUtils {
  static int32ToBytes(num) {
    const buffer = new ArrayBuffer(4);
    const view = new DataView(buffer);
    view.setInt32(0, num, false);
    return new Uint8Array(buffer);
  }

  static int64ToBytes(num) {
    const buffer = new ArrayBuffer(8);
    const view = new DataView(buffer);
    const bigNumber = BigInt(num);
    view.setBigUint64(0, bigNumber, false);
    return new Uint8Array(buffer);
  }

  static bigIntRandom() {
    return BigInt(Math.floor(Math.random() * 2 ** 128));
  }

  static strToBytes(str) {
    return Array.from(str, c => c.charCodeAt(0));
  }
  /*
    function strToBytes(str){
        utf8Encode = new TextEncoder();
        return utf8Encode.encode(str);
    }*/
  /*
    static bufferToBytes( buffer ){
        var target = new Uint8Array(buffer.length);
        buffer.toObject().copy(target);
        return target;
    }*/

  static bufferToBytes(buffer) {
    var target = new Uint8Array(buffer.length);
    var tmpBuf = buffer.toObject();
    for (var i = 0; i < tmpBuf.length; i++) {
      target[i] = tmpBuf[i];
    }
    //tmpBuf.copy(target)
    return target;
  }

  //将一个数字转成hex,如果不满足一定的长度如32,16，则前面补0对齐，如0000000001
  // width的意思是二进制字节数，如32字节的二进制数据，转出来的是64字节长，这时width应该是32
  static numToHex(value, width) {
    let result = value.toString(16);

    if (width == null) {
      // Ensure the value is of even length
      if (result.length % 2) {
        result = '0' + result;
      }
    } else {
      // Pad the value to the required width
      while (result.length < width * 2) {
        result = '0' + result;
      }
    }

    return result;
  }

  static arrayToHex(data) {
    let result = '';
    for (let i = 0; i < data.length; i++) {
      const v = data[i];
      result += HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f];
    }
    return result;
  }

  static hexToArray(str) {
    var value = str;
    if (value.startsWith('0x')) {
      value = value.substring(2);
    }
    const result = new Uint8Array(value.length / 2);
    let offset = 0;
    for (let i = 0; i < result.length; i++) {
      result[i] = parseInt(value.substring(offset, offset + 2), 16);
      offset += 2;
    }
    return result;
  }
}

module.exports.DataUtils = DataUtils;
